package com.smilive.delay.queue.jvm;

import lombok.Data;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * @program: delay_queue_start
 * @Date: 2022-02-08 14:01
 * @Author: smilive
 * @Description: 延迟任务
 */
@Data
public class JvmDelayTask implements Delayed {

    private static final DateTimeFormatter F = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * 默认延迟3秒
     */
    private static final long DELAY_MS = 1000L * 3;

    /**
     * 任务 ID
     */
    private final long taskId;

    /**
     * 创建时间戳
     */
    private final long timestamp;

    /**
     * 过期时间
     */
    private final long expire;

    /**
     * 描述信息
     */
    private final String description;

    public JvmDelayTask(long taskId, long expireSeconds) {
        this.taskId = taskId;
        this.timestamp = System.currentTimeMillis();
        this.expire = this.timestamp + expireSeconds * 1000L;
        this.description = String.format("任务[%s]-创建时间为:%s,超时时间为:%s", taskId,
                LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault()).format(F),
                LocalDateTime.ofInstant(Instant.ofEpochMilli(expire), ZoneId.systemDefault()).format(F));
    }

    public JvmDelayTask(long taskId) {
        this.taskId = taskId;
        this.timestamp = System.currentTimeMillis();
        this.expire = this.timestamp + DELAY_MS;
        this.description = String.format("任务[%s]-创建时间为:%s,超时时间为:%s", taskId,
                LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault()).format(F),
                LocalDateTime.ofInstant(Instant.ofEpochMilli(expire), ZoneId.systemDefault()).format(F));
    }

    /**
     * 需要实现的接口，获得延迟时间   用过期时间-当前时间
     * @param unit
     * @return
     */
    @Override
    public long getDelay(TimeUnit unit) {
        return unit.convert(this.expire - System.currentTimeMillis(),TimeUnit.MILLISECONDS);
    }

    /**
     * 用于延迟队列内部比较排序   当前对象的延迟时间 - 比较对象的延迟时间
     * @param o
     * @return
     */
    @Override
    public int compareTo(Delayed o) {
        return (int)(this.getDelay(TimeUnit.MICROSECONDS) - o.getDelay(TimeUnit.MICROSECONDS));
    }
}
